package br.ucb.cm.main.mainview;

import java.util.Map;

import javax.swing.JOptionPane;

import br.ucb.cm.board.bean.Location;
import br.ucb.cm.board.ui.BoardGame;
import br.ucb.cm.board.ui.BoardPane;
import br.ucb.cm.config.GameInstance;
import br.ucb.cm.config.bean.PieceConfig;
import br.ucb.cm.main.common.GeneralConstants.PlayerEnum;
import br.ucb.cm.main.common.ComputerController;
import br.ucb.cm.main.common.GeneralConstants.PlayerTypeEnum;
import br.ucb.cm.main.common.HumanController;
import br.ucb.cm.main.common.PlayerController;
import br.ucb.cm.main.mainview.ui.Counter;
import br.ucb.cm.main.mainview.ui.GamePane;

public class GameController implements IfcGameController{
	private GamePane gamePane;
	private BoardPane boardPane;
	private PlayerController playerIController;
	private PlayerController playerIIController;
	private Map<Location, PieceConfig> pieceMap;
	private PlayerEnum currentTurn;
	
	public GameController() {
		
		this.gamePane = new GamePane(this);
		this.boardPane = new BoardGame(
				GameInstance.getInstance().getConfig().getBoard().getWidth(), 
				GameInstance.getInstance().getConfig().getBoard().getHeight(), 
				null
		);
		this.pieceMap = GameInstance.getInstance().getConfig().getPieceMap();
		
		init();
	}

	public void init() {
		this.boardPane.setPieceMap(this.pieceMap);
		this.gamePane.setBoardPane(this.boardPane);

		this.playerIController  = PlayerEnum.PLAYER_ONE.getPlayerType() == PlayerTypeEnum.CPU ? new ComputerController(this, boardPane, PlayerEnum.PLAYER_ONE) : new HumanController(this, boardPane, PlayerEnum.PLAYER_ONE);
		this.playerIIController = PlayerEnum.PLAYER_TWO.getPlayerType() == PlayerTypeEnum.CPU ? new ComputerController(this, boardPane, PlayerEnum.PLAYER_TWO) : new HumanController(this, boardPane, PlayerEnum.PLAYER_TWO);
	}
	
	public void startGame() {
		nextTurn();
	}
	
	public void finishedTurn(){
		nextTurn();
	}
	
	private void nextTurn(){
		if(currentTurn == null)
			currentTurn = GameInstance.getInstance().getNewGameConfig().getStartingPlayer();
		else{
			gamePane.getCounter(currentTurn).setTurnOn(false);
			PlayerEnum[] players = PlayerEnum.values();
			currentTurn = players[(currentTurn.ordinal() + 1) % players.length];
		}
		
		
		gamePane.getCounter(currentTurn).setTurnOn(true);
		getPlayerController(currentTurn).useAsController();
	}
	
	private PlayerController getPlayerController(PlayerEnum playerOne) {
		return playerOne == PlayerEnum.PLAYER_ONE ? playerIController : playerIIController;
	}

	public GamePane getGamePane() {
		return gamePane;
	}

	public void refreshStatus(int points, PieceConfig deathPiece, PlayerEnum player) {
		Counter counter = gamePane.getCounter(player);
		
		counter.setPoints(points);
		counter.capturePiece(deathPiece);
	}

	public void callGameToFinish() {
		Counter counterI = gamePane.getCounter(PlayerEnum.PLAYER_ONE);
		Counter counterII = gamePane.getCounter(PlayerEnum.PLAYER_TWO);
		
		gamePane.getBoardPane().setCursor(null);
		if(counterI.getPoints().intValue() > counterII.getPoints().intValue())
			victory(PlayerEnum.PLAYER_ONE);
		else if (counterI.getPoints().intValue() < counterII.getPoints().intValue())
			victory(PlayerEnum.PLAYER_TWO);
		else
			draw();
	}

	private void draw() {
		gamePane.draw();
		JOptionPane.showMessageDialog(gamePane, "O partida terminou empatada.", "Fim do jogo", JOptionPane.INFORMATION_MESSAGE, null);
	}

	private void victory(PlayerEnum player) {
		gamePane.doVictory(player);
		JOptionPane.showMessageDialog(gamePane, "O jogador \"" + player.getName() + "\" venceu!!", "Fim do jogo", JOptionPane.INFORMATION_MESSAGE, null);
	}

}
